package com.zyx.hminterview.day04.boot;

import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.AnnotationConfigUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.GenericApplicationContext;

import java.io.IOException;

public class TestAutoConfiguration {

    public static void main(String[] args) throws IOException {
        GenericApplicationContext context = new GenericApplicationContext();
        AnnotationConfigUtils.registerAnnotationConfigProcessors(context.getDefaultListableBeanFactory());
//        context.getEnvironment().getPropertySources().addLast(new ResourcePropertySource("application.properties"));
        context.registerBean(MyConfig.class);
        context.refresh();

//        System.out.println(AutoConfigurationPackages.get(context.getDefaultListableBeanFactory()));

        for (String name : context.getBeanDefinitionNames()) {
            System.out.println(name);
        }

//        System.out.println(SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration.class, EnableAutoConfiguration.class.getClassLoader()).stream()
//                .filter(name -> !name.equals(OtherConfig.class.getName())).map(name -> "\"" + name + "\"").collect(Collectors.joining(",","{","}")));
    }

    @Configuration
//    @AutoConfigurationPackage
    @EnableAutoConfiguration(excludeName = {"org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration", "org.springframework.boot.autoconfigure.aop.AopAutoConfiguration", "org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration", "org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration", "org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration", "org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration", "org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration", "org.springframework.boot.autoconfigure.context.LifecycleAutoConfiguration", "org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration", "org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration", "org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration", "org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration", "org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration", "org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveDataAutoConfiguration", "org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveRepositoriesAutoConfiguration", "org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration", "org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration", "org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveDataAutoConfiguration", "org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveRepositoriesAutoConfiguration", "org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration", "org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration", "org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration", "org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRepositoriesAutoConfiguration", "org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRestClientAutoConfiguration", "org.springframework.boot.autoconfigure.data.jdbc.JdbcRepositoriesAutoConfiguration", "org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration", "org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration", "org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration", "org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration", "org.springframework.boot.autoconfigure.data.mongo.MongoReactiveRepositoriesAutoConfiguration", "org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration", "org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration", "org.springframework.boot.autoconfigure.data.neo4j.Neo4jReactiveDataAutoConfiguration", "org.springframework.boot.autoconfigure.data.neo4j.Neo4jReactiveRepositoriesAutoConfiguration", "org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration", "org.springframework.boot.autoconfigure.data.r2dbc.R2dbcDataAutoConfiguration", "org.springframework.boot.autoconfigure.data.r2dbc.R2dbcRepositoriesAutoConfiguration", "org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration", "org.springframework.boot.autoconfigure.data.redis.RedisReactiveAutoConfiguration", "org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration", "org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration", "org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration", "org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientAutoConfiguration", "org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration", "org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration", "org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration", "org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration", "org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration", "org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration", "org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration", "org.springframework.boot.autoconfigure.hazelcast.HazelcastJpaDependencyAutoConfiguration", "org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration", "org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration", "org.springframework.boot.autoconfigure.influx.InfluxDbAutoConfiguration", "org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration", "org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration", "org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration", "org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration", "org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration", "org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration", "org.springframework.boot.autoconfigure.jdbc.XADataSourceAutoConfiguration", "org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration", "org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration", "org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration", "org.springframework.boot.autoconfigure.jms.JndiConnectionFactoryAutoConfiguration", "org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration", "org.springframework.boot.autoconfigure.jms.artemis.ArtemisAutoConfiguration", "org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration", "org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration", "org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration", "org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration", "org.springframework.boot.autoconfigure.availability.ApplicationAvailabilityAutoConfiguration", "org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration", "org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration", "org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration", "org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration", "org.springframework.boot.autoconfigure.mail.MailSenderValidatorAutoConfiguration", "org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration", "org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration", "org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration", "org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration", "org.springframework.boot.autoconfigure.neo4j.Neo4jAutoConfiguration", "org.springframework.boot.autoconfigure.netty.NettyAutoConfiguration", "org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration", "org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration", "org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration", "org.springframework.boot.autoconfigure.r2dbc.R2dbcTransactionManagerAutoConfiguration", "org.springframework.boot.autoconfigure.rsocket.RSocketMessagingAutoConfiguration", "org.springframework.boot.autoconfigure.rsocket.RSocketRequesterAutoConfiguration", "org.springframework.boot.autoconfigure.rsocket.RSocketServerAutoConfiguration", "org.springframework.boot.autoconfigure.rsocket.RSocketStrategiesAutoConfiguration", "org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration", "org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration", "org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration", "org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration", "org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration", "org.springframework.boot.autoconfigure.security.rsocket.RSocketSecurityAutoConfiguration", "org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyAutoConfiguration", "org.springframework.boot.autoconfigure.sendgrid.SendGridAutoConfiguration", "org.springframework.boot.autoconfigure.session.SessionAutoConfiguration", "org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfiguration", "org.springframework.boot.autoconfigure.security.oauth2.client.reactive.ReactiveOAuth2ClientAutoConfiguration", "org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration", "org.springframework.boot.autoconfigure.security.oauth2.resource.reactive.ReactiveOAuth2ResourceServerAutoConfiguration", "org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration", "org.springframework.boot.autoconfigure.sql.init.SqlInitializationAutoConfiguration", "org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration", "org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration", "org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration", "org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration", "org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration", "org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration", "org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration", "org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration", "org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration", "org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration", "org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration", "org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration", "org.springframework.boot.autoconfigure.web.reactive.function.client.ClientHttpConnectorAutoConfiguration", "org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration", "org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration", "org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration", "org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration", "org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration", "org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration", "org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration", "org.springframework.boot.autoconfigure.websocket.reactive.WebSocketReactiveAutoConfiguration", "org.springframework.boot.autoconfigure.websocket.servlet.WebSocketServletAutoConfiguration", "org.springframework.boot.autoconfigure.websocket.servlet.WebSocketMessagingAutoConfiguration", "org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration", "org.springframework.boot.autoconfigure.webservices.client.WebServiceTemplateAutoConfiguration", "org.mybatis.spring.boot.autoconfigure.MybatisLanguageDriverAutoConfiguration", "org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration"})
//    @Import(OtherConfig.class)
    static class MyConfig { // 主配置
        @Bean
        public Bean1 bean1() {
            System.out.println("MyConfig bean1()");
            return new Bean1();
        }
    }

    @Configuration
    static class OtherConfig { // 从属配置(自动配置、默认配置)
        @Bean
        @ConditionalOnMissingBean
        public Bean1 bean1() {
            System.out.println("OtherConfig bean1()");
            return new Bean1();
        }
        @Bean
        public Bean2 bean2() {
            return new Bean2();
        }
    }

    static class Bean1 {

    }

    static class Bean2 {

    }
}
